www.gusucode.com > 基于Visual C++高级界面特效制作百例源码程序 > 基于Visual C++高级界面特效制作百例源码程序/code/char13/gridctrllist/InPlaceList.cpp

    






































// InPlaceList.cpp : implementation file
//
// Written by Motty Cohen Copyright (c) 1998.
// (based on Chris Maunder's InPlaceEdit class).
// 
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. If 
// the source code in  this file is used in any commercial application 
// then acknowledgement must be made to the author of this file 
// (in whatever form you wish).
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// Expect bugs!
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "InPlaceList.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CInPlaceList

CInPlaceList::CInPlaceList(CWnd* pParent, CRect& rect, DWORD dwStyle, int nRow, int nColumn, 
						   CString sInitText, UINT nFirstChar)
{
	m_nNumLines = 5;
	m_sInitText = sInitText;
 	m_nRow		= nRow;
 	m_nCol      = nColumn;
 	m_nLastChar = 0; 
	m_bExitOnArrows = FALSE; //(nFirstChar != VK_LBUTTON);	// If mouse click brought us here,

	// Create the ListBox, not using dwStyle argument for now
 	DWORD dwStyle2 = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL|
 					CBS_DROPDOWNLIST|CBS_AUTOHSCROLL;
	int nHeight = rect.Height();
	rect.bottom = rect.bottom + m_nNumLines*nHeight + ::GetSystemMetrics(SM_CYHSCROLL);
	if (!Create(dwStyle2, rect, pParent, IDC_IPLIST)) return;

	// Add the strings, Ask them from the parent
	pParent->SendMessage( IPLM_FILL, nColumn, (LPARAM)this );

	// Get the maximum width of the text strings
	/*
	int nMaxLength = 0;
	CClientDC dc(GetParent());
	CFont* pOldFont = dc.SelectObject(pParent->GetFont());

	for (int i = 0; i < Items.GetSize(); i++) 
		nMaxLength = max(nMaxLength, dc.GetTextExtent(Items[i]).cx);
	
	nMaxLength += (::GetSystemMetrics(SM_CXVSCROLL) + dc.GetTextExtent(_T(" ")).cx*2);
	dc.SelectObject(pOldFont);
	
	if (rect.right < rect.left + nMaxLength + 4)
		rect.right = rect.left + nMaxLength + 4;
	*/

	// Resize the edit window and the drop down window
	MoveWindow(rect);

	SetFont(pParent->GetFont());
	SetItemHeight(-1, nHeight);

	SetHorizontalExtent(0); // no horz scrolling

	// Set the initial text to m_sInitText
	if (SelectString(-1, m_sInitText) == CB_ERR) 
		SetWindowText(m_sInitText);		// No text selected, so restore what was there before

 	SetFocus();
}

CInPlaceList::~CInPlaceList()
{
}

BEGIN_MESSAGE_MAP(CInPlaceList, CListBox)
	//{{AFX_MSG_MAP(CInPlaceList)
	ON_WM_KILLFOCUS()
	ON_WM_NCDESTROY()
	ON_WM_CHAR()
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	ON_WM_LBUTTONUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

	//ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup) // for ComboBox

/////////////////////////////////////////////////////////////////////////////
// CInPlaceList message handlers

void CInPlaceList::OnKillFocus(CWnd* pNewWnd) 
{
	CListBox::OnKillFocus(pNewWnd);
    EndSelect();
}

// If an arrow key (or associated) is pressed, then exit if
//  a) The Ctrl key was down, or
//  b) m_bExitOnArrows == TRUE
void CInPlaceList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
		 nChar == VK_DOWN  || nChar == VK_UP   ||
		 nChar == VK_RIGHT || nChar == VK_LEFT) &&
		(m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
	{
		m_nLastChar = nChar;
		GetParent()->SetFocus();
		return;
	}
    if (nChar == VK_ESCAPE) 
    {
        SetWindowText(m_sInitText);    // restore previous text
        m_nLastChar = nChar;
        GetParent()->SetFocus();
        return;
    }

	CListBox::OnKeyDown(nChar, nRepCnt, nFlags);
}

// Need to keep a lookout for Tabs, Esc and Returns. These send a 
// "KeyUp" message, but no "KeyDown". That's why I didn't put their
// code in OnKeyDown. (I will never understand windows...)
void CInPlaceList::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if (nChar == VK_ESCAPE)
	{
		SetWindowText(m_sInitText);	// restore previous text
		GetParent()->SetFocus();	// This will destroy this window
		return;
	}
	if (nChar == VK_TAB || nChar == VK_RETURN)
	{
		GetParent()->SetFocus();	// This will destroy this window
		return;
	}

	CListBox::OnKeyUp(nChar, nRepCnt, nFlags);
}

void CInPlaceList::EndSelect()
{
    CString		csItemText;
	DWORD		dwUserData = 0;
	int			nItem = GetCurSel();

	if ( nItem != LB_ERR )
	{
		dwUserData = GetItemData(nItem);
		GetText( nItem, csItemText);
	}
	else
	{
		csItemText = m_sInitText;
	}

    // Send Notification to parent (this was originally designed for listviews,
    // so we use listview structures and messages)

    LV_DISPINFO dispinfo;

    dispinfo.hdr.hwndFrom = GetParent()->GetSafeHwnd();
    dispinfo.hdr.idFrom   = GetDlgCtrlID();
    dispinfo.hdr.code     = LVN_ENDLABELEDIT;
 
    dispinfo.item.mask       = LVIF_TEXT|LVIF_PARAM;
    dispinfo.item.iItem      = m_nRow;
    dispinfo.item.iSubItem   = m_nCol;
    dispinfo.item.pszText    = LPTSTR((LPCTSTR)csItemText);
    dispinfo.item.cchTextMax = csItemText.GetLength();
    dispinfo.item.lParam     = (LPARAM)dwUserData; 
 
    // Send a message to the parent of this edit's parent, telling the parent's parent
    // that the parent of this edit ctrl has recieved a LVN_ENDLABELEDIT message. 
    // Makes perfect sense, no? :)
    GetParent()->GetParent()->SendMessage(WM_NOTIFY, GetParent()->GetDlgCtrlID(), 
                                          (LPARAM)&dispinfo );
 
    DestroyWindow();
}
void CInPlaceList::OnNcDestroy() 
{
	CListBox::OnNcDestroy();
	delete this;
}

void CInPlaceList::OnLButtonUp( UINT nFlag, CPoint pt )
{
	CListBox::OnLButtonUp( nFlag, pt );
	EndSelect();
}

void CInPlaceList::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	CListBox::OnChar(nChar, nRepCnt, nFlags);

	// this event is for the next version to implement
	// Search-As-You-Type functionality.

}

/*
void CInPlaceList::OnCloseup() 
{
	//if (!::IsWindow(GetSafeHwnd())) return;
	//GetParent()->SetFocus();
}
*/